#include "mduserhandle.h"
//以下是main.cpp文件
#include "tradehandler.h"
#include <unistd.h> // 包含 sleep 函数的头文件
#include <nlohmann/json.hpp>
#include <memory>
#include <yaml-cpp/yaml.h>
#include <cstdlib> // for getenv
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <array>
#include <execinfo.h>
#include <thread>  // 为 std::this_thread 添加
#include <csignal>  // 添加信号处理头文件
#include "tcp_server.h"
#include <queue>
#include <mutex>
#include <condition_variable>
#include "logger.h"

// 定义全局指针，方便在WebSocket处理函数中访问
std::unique_ptr<CTraderHandler> trader;
std::unique_ptr<CMduserHandler> mduser;

// 定义订单请求结构
struct OrderRequest {
    std::string instrument;
    std::string exchange;
    std::string direction;
    double price;
    int volume;
    std::string offset;
    TcpConnection* conn;  // 用于发送响应
};

// 添加订单请求队列和相关同步对象
std::queue<OrderRequest> orderQueue;
std::mutex orderMutex;
std::condition_variable orderCV;
bool running = true;

// 加载配置的辅助函数
void loadConfig(YAML::Node& config) {
    try {
        config = YAML::LoadFile("config/config.yaml");
    } catch (const YAML::Exception& e) {
        throw std::runtime_error("无法加载配置文件: " + std::string(e.what()));
    }
}

// 获取环境变量的辅助函数
std::string getEnvVar(const std::string& key) {
    const char* val = std::getenv(key.c_str());
    if (val == nullptr) {
        throw std::runtime_error("环境变量未设置: " + key);
    }
    return std::string(val);
}

using json = nlohmann::json;

void initLogger() {
    Logger::info("日志系统初始化成功");
}

// 在 loadConfig 函数后添加检查时间的辅助函数
bool shouldExit(const std::string& dayExitTime, const std::string& nightExitTime) {
    time_t now = time(nullptr);
    struct tm* ltm = localtime(&now);
    
    // 解析两个退出时间 (格式: "HH:MM")
    int dayHour, dayMin, nightHour, nightMin;
    sscanf(dayExitTime.c_str(), "%d:%d", &dayHour, &dayMin);
    sscanf(nightExitTime.c_str(), "%d:%d", &nightHour, &nightMin);
    
    // 只有当小时和分钟都相等时才退出
    if ((ltm->tm_hour == dayHour && ltm->tm_min == dayMin) || 
        (ltm->tm_hour == nightHour && ltm->tm_min == nightMin)) {
        return true;
    }
    return false;
}

int main(int argc, char *argv[])
{
    // 在最开始初始化日志系统
    initLogger();
    Logger::info("程序启动");

    try {
        // 加载配置
        YAML::Node config;
        loadConfig(config);
        Logger::info("配置文件加载成功");
        
        // 获取环境变量中的密码
        std::string password = getEnvVar("CTP_PASSWORD");

        // 使用智能指针替代原来的裸指针
        trader = std::make_unique<CTraderHandler>(
            config["ctp"]["broker_id"].as<std::string>(),
            config["ctp"]["user_id"].as<std::string>(),
            password,
            config["ctp"]["flow_path"].as<std::string>(),
            config["ctp"]["trader"]["front_addr"].as<std::string>(),
            config["ctp"]["trader"]["app_id"].as<std::string>(),
            config["ctp"]["trader"]["auth_code"].as<std::string>()
        );

        mduser = std::make_unique<CMduserHandler>(
            config["ctp"]["broker_id"].as<std::string>(),
            config["ctp"]["user_id"].as<std::string>(),
            password,
            config["ctp"]["flow_path"].as<std::string>(),
            config["ctp"]["md"]["front_addr"].as<std::string>()
        );
        
        // 初始化连接和登录
        mduser->connect();
        trader->connect();
        // mduser->login();
        sleep(2);
        // trader->login();
        sleep(2);
        trader->settlementinfoConfirm();
        sleep(2);

        // 创建TCP服务器
        TcpServer server(config["server"]["port"].as<int>());
        mduser->setServer(&server);
        trader->setServer(&server);
        // 设置消息处理函数
        server.set_message_handler([&](const std::string& data, TcpConnection* conn) {
            Logger::info("收到客户端消息: " + data);
            
            try {
                Logger::info("开始解析JSON...");
                auto msg = json::parse(data);
                
                Logger::info("JSON解析成功,action=" + msg["action"].get<std::string>());
                std::string action = msg["action"].get<std::string>();

                if (action == "subscribe") {
                    std::string instrument = msg["data"]["instrument"].get<std::string>();
                    Logger::info("处理subscribe请求...");
                    Logger::info("订阅品种: " + instrument);
                    
                    mduser->subscribe(instrument);
                    json response = {
                        {"type", "response"},
                        {"action", "subscribe"},
                        {"status", "success"},
                        {"data", {{"instrument", instrument}}}
                    };
                    Logger::info("发送响应: " + response.dump());
                    conn->send(response.dump());
                }

                else if (action == "unsubscribe") {
                    std::string instrument = msg["data"]["instrument"].get<std::string>();
                    Logger::info("处理unsubscribe请求...");
                    Logger::info("取消订阅品种: " + instrument);

                    mduser->unsubscribe(instrument);
                    json response = {
                        {"type", "response"},
                        {"action", "unsubscribe"},
                        {"status", "success"},
                        {"data", {{"instrument", instrument}}}
                    };
                    Logger::info("发送响应: " + response.dump());
                    conn->send(response.dump());
                }
                
                else if (action == "orderInsert") {
                    Logger::info("处理orderInsert请求...");
                    Logger::info("下单数据: " + msg["data"].dump());
                    int r = trader->orderInsert(
                        msg["data"]["instrument"].get<std::string>(),
                        msg["data"]["exchange"].get<std::string>(),
                        msg["data"]["direction"].get<std::string>(),
                        msg["data"]["price"].get<double>(),
                        msg["data"]["volume"].get<int>(),
                        msg["data"]["offect"].get<std::string>(),
                        msg["data"]["order_ref"].get<std::string>()
                    );
                    json response = {
                        {"type", "response"},
                        {"action", "orderInsert"},
                        {"status", "success"},
                        {"data", {{"result", r}}}
                    };
                    conn->send(response.dump());
                    Logger::info("下单结果: " + std::to_string(r));
                }
                           
                else if (action == "getPosition") {
                    Logger::info("处理getPosition请求...");
                    int r = trader->getPosition();
                    json response = {
                        {"type", "response"},
                        {"action", "getPosition"},
                        {"status", "success"},
                        {"data", {{"result", r}}}
                    };
                    conn->send(response.dump());
                }
                
                else if (action == "getAccount") {
                    Logger::info("处理getAccount请求...");
                    int r = trader->getAccount();
                    json response = {
                        {"type", "response"},
                        {"action", "getAccount"},
                        {"status", "success"},
                        {"data", {{"result", r}}}
                    };
                    conn->send(response.dump());
                }

                else if (action == "getTrade") {
                    Logger::info("处理getTrade请求...");
                    int r = trader->getTrade();
                    json response = {
                        {"type", "response"},
                        {"action", "getTrade"},
                        {"status", "success"},
                        {"data", {{"result", r}}}
                    };
                    conn->send(response.dump());
                }

                else if (action == "getOrder") {
                    Logger::info("处理getOrder请求...");
                    int r = trader->getOrder(msg["data"]["exchange"].get<std::string>());
                    json response = {
                        {"type", "response"},
                        {"action", "getOrder"}, 
                        {"status", "success"},
                        {"data", {{"result", r}}}
                    };
                    conn->send(response.dump());
                }

                else if (action == "orderCancel") {
                    Logger::info("处理orderCancel请求...");
                    std::string sid = msg["data"]["sid"].get<std::string>();
                    std::string instrument = msg["data"]["instrument"].get<std::string>();
                    std::string exchange = msg["data"]["exchange"].get<std::string>();
                    
                    // 添加合约和交易所的判断
                    Logger::info("检查合约代码: " + instrument + ", 交易所: " + exchange);
                    // bool isTargetInstrument = (instrument == "rb2505");
                    // bool isTargetExchange = (exchange == "SHFE");
                    // Logger::info("合约匹配结果: " + std::to_string(isTargetInstrument) + 
                    //            ", 交易所匹配结果: " + std::to_string(isTargetExchange));
                    
                    // std::string sid_ = "      217146";
                    // bool eql = sid == sid_;
                    // Logger::info("订单编号是否相等: " + std::to_string(eql));
                    // int r = trader->orderCancel("rb2505", "SHFE", sid);

                    int r = trader->orderCancel(instrument, exchange, sid);
                    json response = {
                        {"type", "response"},
                        {"action", "orderCancel"},
                        {"status", "success"},
                        {"data", {{"result", r}}}
                    };
                    conn->send(response.dump());
                    Logger::info("订单取消结果: " + std::to_string(r));
                }
                
                else if (action == "heartbeat") {
                    Logger::info("处理heartbeat请求...");
                    json response = {
                        {"type", "response"},
                        {"action", "heartbeat"},
                        {"status", "success"}
                    };
                    conn->send(response.dump());
                }

                else {  
                    Logger::error("未知的action类型: " + action);
                }
            } catch (const std::exception& e) {
                Logger::error("处理消息时发生错误: " + std::string(e.what()));
                json error_response = {
                    {"type", "error"},
                    {"message", e.what()}
                };
                conn->send(error_response.dump());
            }
        });

        // 启动订单处理线程
        // std::thread orderThread(processOrders);

        // 启动服务器
        server.start();

        // 添加信号处理
        // std::signal(SIGINT, [](int) {
        //     // 清理资源并退出
        //     running = false;
        //     orderCV.notify_one();
        //     exit(0);
        // });

        // 保持主线程运行
        std::string dayExitTime = config["server"]["day_exit_time"].as<std::string>();
        std::string nightExitTime = config["server"]["night_exit_time"].as<std::string>();
        Logger::info("程序将在以下时间退出: 日间 " + dayExitTime + ", 夜间 " + nightExitTime);
        
        while (running) {
            if (shouldExit(dayExitTime, nightExitTime)) {
                Logger::info("达到预定退出时间, 开始优雅退出程序");
                
                // 1. 先停止接受新的连接
                server.stop();  // 这会停止接受新连接并清理现有连接
                
                // 2. 释放行情和交易接口
                Logger::info("正在释放行情接口...");
                mduser->release();
                
                Logger::info("正在释放交易接口...");
                trader->release();
                
                running = false;
                break;
            }
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }

        // 等待所有资源释放完成
        std::this_thread::sleep_for(std::chrono::seconds(2));
        Logger::info("程序正常退出");
        return 0;
    } catch (const std::exception& e) {
        Logger::error("错误: " + std::string(e.what()));
        return 1;
    }
}